home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX350 / SECT.BAK < prev    next >
Encoding:
Text File  |  2001-02-09  |  18.0 KB  |  752 lines

  1. /* sect.c */
  2.  
  3. /* 
  4.  * Aug-23-88 jye. Change and add codes so that can be used for MS-DOS
  5.  * Dec-20-89 jye. Free a bug that HDX gives a error message when CD-ROM 
  6.  *                  is busy. 
  7.  */
  8.  
  9. #include "obdefs.h"
  10. #include "osbind.h"
  11. #include "mydefs.h"
  12. #include "part.h"
  13. #include "hdx.h"
  14. #include "addr.h"
  15. #include "error.h"
  16.  
  17. #define    ZBUFSIZ    0x4000        /* about 16k == 32 sectors */
  18. #define    ZCOUNT    (ZBUFSIZ/0x200)    /* ZCOUNT = 32 */
  19. #define MAXUNITS 16            /* max number of logical units */
  20.  
  21. #define PUNINFO struct _punifno
  22. PUNINFO {
  23.         WORD puns;    /* number of physical units */
  24.         BYTE pun[MAXUNITS];
  25.         LONG partition_start[MAXUNITS]; /* offset to partition on */
  26.                                         /* physical unit */
  27. };
  28. extern long ostack;        /* old stack pointer */
  29. extern UWORD errcode();        /* function to return error code */
  30. extern int yesscan;        /* the flag for the func. IBMGPART use */
  31. extern long sptrk;        /* the sector per track */
  32. extern int npart;        /* the number of partitions */
  33. extern int ext;            /* the index of extended partition */
  34. extern int extend;        /* the index of end extended partition */
  35. extern int showmany;    /* the flag for show the too many device alert box */
  36. extern char ttscsi;        /* the flag for SCSI if set */
  37. extern int t_scsi();    /* the assembly codes for check SCSI drive */
  38. extern int needscan;    /* TRUE: if it is the first time to scan the units */
  39.  
  40.  
  41. /*
  42.  * Logical-to-dev+partition mapping table.
  43.  */
  44. int nlogdevs;                /* # logical devices */
  45. LOGMAP logmap[EXTRALOGD];    /* logical dev map */
  46. int livedevs[MAXPHYSDEVS];    /* live devs flags; 1: device is alive */
  47. int typedev = 0x0000;        /* if set, driver is a removable driver */
  48. int typedrv = 0x0000;        /* if set, driver is a SCSI driver */
  49.  
  50.  
  51. /*
  52.  * Rebuild logical-to-physical mapping
  53.  * by reading and interpreting the root
  54.  * blocks for all physical devs.
  55.  *
  56.  */
  57.  
  58. rescan(flag, znm)
  59.  
  60. int flag;    /* 0: don't report medium change error; */
  61.             /* non-0: report medium change error; */
  62. int znm;    /* 1: do zero & markbad; 0: do partition & format */
  63.  
  64. {
  65.     int dev, scan=0;
  66.     char buf[512];
  67.     char sendata[16];
  68.     int partno, ret, inqret, i;
  69.     PART *partinfo;
  70.     char mask = 0x80;    /* 7th bit is set on */
  71.     int setmask;
  72.     int maxloop;
  73.  
  74.     /* disable all logical and physical devs */
  75.     for (dev = 0; dev < EXTRALOGD; ++dev)
  76.         logmap[dev].lm_physdev = -1;
  77.  
  78.     for (dev = 0; dev < MAXPHYSDEVS; ++dev)
  79.         livedevs[dev] = 0;
  80.  
  81.     /*
  82.      * Scan all physical devs
  83.      * and pick up partition structures.
  84.      */
  85.     nlogdevs = 0;
  86.     showmany = 0;
  87.  
  88. rerescan:
  89.     for (dev = 0; dev < 8; ++dev)
  90.     {
  91.         /* initialize the buffer */
  92.         for (i = 0; i < 16; i++)        {
  93.             sendata[i] = 0;
  94.         }
  95.  
  96.         /* check see the drive is a what kind of drive */
  97.            ostack = Super(NULL);
  98.            delay();
  99.         inqret = inquiry(dev, (WORD)16, sendata);
  100.            delay();
  101.            Super(ostack);
  102.         setmask = 0x0001;
  103.         if (inqret & 0x08)    { /* the device is busy */
  104.             continue;
  105.         }
  106.         /* ret not equal OK, it may be a regular hard drive */
  107.         if (inqret == OK)         {     /* it is not a regular hard drive */
  108.             if (sendata[0])      {    /* it is not a hard drive */
  109.                 continue;
  110.             } else if (sendata[1] & mask)    { /* it is a removable drive */
  111.                 ;            /* don't set the SCSI bit */
  112.             } else {
  113.                   /* it is a SCSI drive */
  114.                 /* set the relative bit, 1 is a SCSI, other is not */
  115.                 typedrv |= setmask << dev;
  116.             }
  117.         }
  118.         if ((ret = getroot(dev, buf, (SECTOR)0)) < 0) {
  119.             if (znm)  rangelog(dev);
  120.             continue;
  121.         } else {        /* ret >= 0 */
  122.             if (ret > 0) {
  123.                 if (flag) {    /* if non-0, report error if medium changed */
  124.                     if (tsterr(ret) == OK)
  125.                         erasemsg();
  126.                         return ERROR;
  127.                 }
  128.                 if ((ret = getroot(dev, buf, (SECTOR)0))) {    /* try again */
  129.                     if (ret > 0 && flag && tsterr(ret) == OK)    {
  130.                         erasemsg();
  131.                         return ERROR;
  132.                     } else if ((ret > 0) && (!flag))    {
  133.                         if ((inqret == OK) && (sendata[1] & mask))    { 
  134.                             /* it is a removable drive */
  135.                             /* but forget insert the cartridge */
  136.                             err(instdrv);
  137.                             erasemsg();
  138.                             return ERROR;
  139.                         }
  140.                     }
  141.                     if (znm)    {
  142.                         rangelog(dev);
  143.                     }
  144.                     continue;
  145.                 }
  146.             }
  147.             if (inqret == OK)     {  /* it is a SCSI drive */
  148.                 if (sendata[1] & mask)    { /* it is a removable drive */
  149.                     /* set the relative bit, 1 is a removable, other is not */
  150.                     typedev |= setmask << dev;
  151.                 }
  152.             }
  153.             livedevs[dev] = 1;
  154.             yesscan = 1;
  155.             if (stgpart(dev, buf, (PART *)&partinfo) == ERROR)    {
  156.                 erasemsg();
  157.                 return ERROR;
  158.             }
  159.             if (ext != NO_EXT)    {
  160.                 sortpart(partinfo,SCAN_BS); 
  161.             }
  162.         for (partno = 0; partno < npart; ++partno) {
  163.             if ((partinfo[partno].p_flg & P_EXISTS) &&
  164.                 (partinfo[partno].p_siz != (SECTOR)0) &&
  165.                 (((partinfo[partno].p_id[0] == 'G') &&
  166.                  (partinfo[partno].p_id[1] == 'E') &&
  167.                  (partinfo[partno].p_id[2] == 'M'))   ||
  168.                  ((partinfo[partno].p_id[0] == 'B') &&
  169.                  (partinfo[partno].p_id[1] == 'G') &&
  170.                  (partinfo[partno].p_id[2] == 'M'))))   
  171.             {
  172.                 if (nlogdevs > EXTRALOGD)    {
  173.                     continue;
  174.                 }
  175.                 logmap[nlogdevs].lm_physdev = dev;
  176.                 logmap[nlogdevs].lm_partno = partno;
  177.                 logmap[nlogdevs].lm_start =  partinfo[partno].p_st;
  178.                 logmap[nlogdevs].lm_siz =      partinfo[partno].p_siz;
  179.                 ++nlogdevs;
  180.                 if (nlogdevs == MAXLOGDEVS)         {
  181.                     showmany = 1;
  182.                 }
  183.             }
  184.         }
  185.     }
  186.     inipart(partinfo, npart);
  187.     if (partinfo > 0)    Mfree(partinfo);
  188.     }
  189.     erasemsg();
  190.     return OK;
  191. }
  192.  
  193. /* rerange the partition informations. */
  194.  
  195.  sortpart(pinfo, type)
  196.  PART *pinfo;
  197.  int type;                /* USER_ED = 1: for user interface use */
  198.                          /* SCAN_BS = 0: for rescan() and laybs() use */
  199.  {
  200.      int i, j, k;
  201.     PART rpart[2];
  202.  
  203.     if (ext == NO_EXT) return OK;    /* don't need sort */
  204.     for (i = 0; i < 2; i++)    { /* initialize the temple space */
  205.         rpart[i].p_flg = 0L;
  206.         rpart[i].p_st = 0L;
  207.         rpart[i].p_siz = 0L;
  208.         for (k = 0; k < 3; k++)
  209.             rpart[i].p_id[k] = '0';
  210.     }
  211.     /* save the partitions that after the extened partitions */
  212.     for (i = ext+1, j=0; i < 4; i++, j++)        {
  213.         if (pinfo[i].p_flg & P_EXISTS)    {
  214.             rpart[j].p_flg = P_EXISTS;
  215.             rpart[j].p_st = pinfo[i].p_st;
  216.             rpart[j].p_siz = pinfo[i].p_siz;
  217.             for (k = 0; k < 3; k++)
  218.                 rpart[j].p_id[k] = pinfo[i].p_id[k];
  219.         } 
  220.     }
  221.     /* move the extened partition to the front */
  222.      for (i=4, j = ext; i < npart; i++, j++)    {
  223.         if (pinfo[i].p_flg & P_EXISTS)    {
  224.             pinfo[j].p_flg = P_EXISTS;
  225.             pinfo[j].p_st = (type)?(pinfo[i].p_st):(pinfo[i].p_st + ROOTSECT);
  226.             pinfo[j].p_siz = (type)?(pinfo[i].p_siz):(pinfo[i].p_siz-ROOTSECT);
  227.             for (k = 0; k < 3; k++)
  228.                 pinfo[j].p_id[k] = pinfo[i].p_id[k];
  229.         } else { j--;}    /* stay with that space */
  230.     }
  231.     /* copy the not extended partitions back after the extended partitions */
  232.      for (i=0; i < 2; i++, j++)    {
  233.         if (rpart[i].p_flg & P_EXISTS)    {
  234.             pinfo[j].p_flg = P_EXISTS;
  235.             pinfo[j].p_st = rpart[i].p_st;
  236.             pinfo[j].p_siz = rpart[i].p_siz;
  237.             for (k = 0; k < 3; k++)
  238.                 pinfo[j].p_id[k] = rpart[i].p_id[k];
  239.         } else {j--;}
  240.     }
  241.     for (i = j; i < npart; i++)    { /* set the rest to 0 */
  242.         pinfo[i].p_flg = 0L;
  243.         pinfo[i].p_st = 0L;
  244.         pinfo[i].p_siz = 0L;
  245.         for (k = 0; k < 3; k++)
  246.             pinfo[i].p_id[k] = '0';
  247.     }
  248. }
  249.  
  250.  
  251. /* 
  252.  * check to find out the exist of device
  253.  */
  254.  
  255. rangelog(dev)
  256.  
  257. int dev;
  258.  
  259. {
  260.     PUNINFO *divinfo;
  261.     int devnum;
  262.  
  263.     ostack = Super(NULL);
  264.     divinfo = ((PUNINFO *) *((long *)(0x516)));
  265.     for (devnum = 0; devnum < MAXUNITS; ++devnum)    {
  266.         if ((int)(divinfo->pun[devnum] & 0x07) == dev)    {
  267.             delay();
  268.             nlogdevs++;
  269.         }
  270.     }
  271.     Super(ostack);
  272. }
  273.  
  274. /*
  275.  * From a PHYSICAL device unit (0->7)
  276.  * and a partition number (0->3), figure
  277.  * out the LOGICAL disk number ('C'->'P').
  278.  *
  279.  * return the LOGICAL disk number or
  280.  * ERROR if the PHYSICAL device doesn't exist.
  281.  *
  282.  */
  283. phys2log(pdev, pno)
  284. int  pdev;    /* physical device unit */
  285. int  pno;    /* partition number (0 -> 3) */
  286. {
  287.     int logdev;        /* index to step through partitions of a phys unit */
  288.  
  289.     for (logdev = 0; logdev < EXTRALOGD; logdev++) {
  290.         if (logmap[logdev].lm_physdev == pdev &&
  291.             logmap[logdev].lm_partno == pno)
  292.             return ('C'+logdev);
  293.     }
  294.     return ERROR;
  295. }
  296.  
  297.  
  298. /*
  299.  * Map block on logical device to
  300.  * block on physical device;
  301.  * return ERROR if the logical device
  302.  * doesn't exist.
  303.  */
  304. log2phys(adev, ablk)
  305. int *adev;
  306. SECTOR *ablk;
  307. {
  308.     int dev;
  309.     char xbuf[256];
  310.     
  311.     dev = *adev;
  312.     if (dev >= 0 && dev <= 15)
  313.     return OK;
  314.  
  315.     dev = toupper(dev);
  316.     if (dev >= 'C' && dev <= 
  317.                 ('C'+EXTRALOGD)) /* from C to 't' are 50 logic device */
  318.     {
  319.     dev -= 'C';
  320.     *adev = logmap[dev].lm_physdev;
  321.     *ablk = logmap[dev].lm_start + *ablk;
  322.     return OK;
  323.     }
  324.  
  325.     return ERROR;
  326. }
  327.  
  328.  
  329.  
  330. /*
  331.  * Return physical starting block# of a partition
  332.  *
  333.  */
  334. SECTOR 
  335. logstart(ldev)
  336. int ldev;    /* logical device */
  337. {
  338.     ldev = toupper(ldev);
  339.     if (ldev >= 'C' && ldev <= 
  340.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  341.         ldev -= 'C';
  342.         return (logmap[ldev].lm_start);
  343.     }
  344.     return ERROR;
  345. }
  346.  
  347.  
  348.  
  349. /*
  350.  * Return physical starting block# of a partition's data block.
  351.  *
  352.  */
  353. SECTOR 
  354. logend(ldev)
  355. int ldev;    /* logical device */
  356. {
  357.     ldev = toupper(ldev);
  358.     if (ldev >= 'C' && ldev <= 
  359.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  360.         ldev -= 'C';
  361.         return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
  362.     }
  363.     return ERROR;
  364. }
  365.  
  366.  
  367. #define    MFM 17        /* sectors per track for MFM */
  368. #define    RLL 26        /* sectors per track for RLL */
  369.  
  370.  
  371. /*
  372.  * Check if dev's root block is intact.
  373.  * Return number of sectors per track on disk.
  374.  *
  375.  */
  376. chkroot(dev, bs)
  377. int dev;
  378. char *bs;
  379. {
  380.     extern long get3bytes();
  381.     extern long get4bytes();
  382.     SETMODE *mb;
  383.     int i, ret, set, scsidrv, mask=0x0001;
  384.     int cyl, head;
  385.     SECTOR size, msiz;    /* size of media */
  386.     char buf[512], sendata[32];
  387.     long dmaptr, tmpptr;
  388.     char *dmahigh=0xffff8609,
  389.          *dmamid=0xffff860b,
  390.          *dmalow=0xffff860d;
  391.     
  392.     size = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz;
  393.     
  394.     ostack = Super(NULL);
  395.     
  396.     if (dev > 7)    {    /* it is a scsi drive */
  397.         if ((ret = readcap(dev, 0, (long)0, sendata)) == OK) {
  398.             msiz = get4bytes(sendata) + 1;
  399.             if (size != msiz)
  400.                 ret = ERROR;
  401.             delay();
  402.             Super(ostack);
  403.             return(ret);
  404.         }
  405.         goto chkerr;
  406.     }
  407.  
  408.     /* Get format parameters/ disk size from media */
  409.     set = typedev & (mask << dev);
  410.     scsidrv = typedrv & (mask << dev);
  411.     for (i = 0; i < 32; i++)
  412.         sendata[i] = 0;
  413.     if ((set) || (scsidrv))    {
  414.         ret = mdsense(dev, 4, 0, 32, sendata);     /* use page code 4, but get */
  415.                                             /* info from the mdsense header */
  416.         if (!get3bytes(sendata+5))    {        /* no hsize retured */
  417.             ret = mdsense(dev, 0, 0, 16, sendata);/* use page code 4, but get */
  418.             if (!get3bytes(sendata+5))    {        /* no hsize retured */
  419.                 err(needinfo);
  420.                 delay();
  421.                 Super(ostack);
  422.                 return(-3);
  423.             }
  424.         }
  425.     } else    {
  426.         ret = mdsense(dev, 0, 0, 22, sendata);
  427.     }
  428.  
  429. chkerr:
  430.     delay();
  431.     Super(ostack);
  432.     
  433.     if (ret != 0) {
  434.         ret = errcode(dev);
  435.         if (tsterr(ret) != OK) 
  436.             return ERROR;
  437.         return (-3);    /* don't have to show the alert box */
  438.     }
  439.     
  440.     /* check what kind of sense data it returned  */
  441.     /* If full SCSI, will return number of blocks */
  442.     /* on disk at byte 5, 6 and 7.  If Adaptec,   */
  443.     /* will return 0 for number of blocks on disk */
  444.     /* on SCSI. */
  445.     
  446.     if (!(msiz = get3bytes(sendata+5))) {    /* no disk size returned? */
  447.         /* Yup, ie., it's adaptec's.  Interpret as SETMODE structure */
  448.         mb = (SETMODE *)sendata;
  449.     /* get number of cylinders */
  450.     cyl = mb->smd_cc[0];
  451.     cyl <<= 8;
  452.     cyl |= mb->smd_cc[1];
  453.     
  454.     /* get number of heads */
  455.     head = mb->smd_dhc;
  456.     
  457.     msiz = (SECTOR)head * (SECTOR)cyl * MFM;
  458.     
  459.     for (i = 0; i < 20; i++) {
  460.         if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
  461.         
  462.         /* find out whether data has been transferred, by
  463.               checking if dma pointer has been moved.      */
  464.  
  465.            ostack = Super(NULL);    /* get into Supervisor mode */
  466.            
  467.         dmaptr = *dmahigh;
  468.         dmaptr &= 0x0000003f;
  469.         dmaptr <<= 16;
  470.         tmpptr = *dmamid;
  471.         tmpptr &= 0x000000ff;
  472.         tmpptr <<= 8;
  473.         dmaptr |= tmpptr;
  474.         tmpptr = *dmalow;
  475.         tmpptr &= 0x000000ff;
  476.         dmaptr |= tmpptr;
  477.         
  478.             delay();
  479.             Super(ostack);        /* back to user mode */
  480.             
  481.         if (dmaptr != buf)
  482.             break;
  483.         } else {            /* rdsects return an error */
  484.         if (tsterr(ret) == OK) {
  485.                 break;
  486.         }
  487.             }
  488.         }
  489.     
  490.     if (ret == MDMCHGD)        /* check if error occurred */
  491.         return (ret);
  492.        
  493.     /* Determine if media is MFM or RLL */
  494.     if (i < 20)
  495.         msiz = (SECTOR)head * (SECTOR)cyl * RLL;
  496.     }
  497.  
  498.         
  499.     if (size != msiz)
  500.         ret = ERROR;
  501.     else 
  502.         ret = OK;
  503.         
  504.     return (ret);
  505. }
  506.  
  507.  
  508. /*
  509.  * Chkparm()
  510.  *    Check if given logical device has the asssumed parameters.
  511.  * Assumptions are:
  512.  *    - 512 bytes/sector
  513.  *    - 2 sectors/cluster
  514.  *    - 1 reserved sector
  515.  *    - 2 FATs
  516.  *
  517.  * Input:
  518.  *    ldev - logical device number ('C' -> 'P').
  519.  *
  520.  * Return:
  521.  *    OK - parameters of partition match the assumptions
  522.  *    ERROR - something went wrong.
  523.  *
  524.  * Comment:
  525.  *    Number of FATs is assumed to be 2.  Cannot check this 
  526.  * because previous version of HDX did not put that in the boot
  527.  * sector.
  528.  */
  529. chkparm(ldev)
  530. int ldev;
  531. {
  532.     char bs[512];        /* boot sector */
  533.     BOOT *boot;            /* boot structure */
  534.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  535.     int ret;
  536.  
  537.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  538.         if (tsterr(ret) != OK)
  539.             err(bootread);
  540.         ret = ERROR;
  541.         goto parmend;
  542.     }    
  543.  
  544.     boot = (BOOT *)bs;
  545.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  546.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  547.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  548.     if (bps % BPS            /* bytes per sector == ratio of 512 ? */
  549.     || res != 1) {            /* num sectors reserved == 1 ? */
  550.     ret = ERROR;            /* Nope, different from assumptions */
  551.     goto parmend;
  552.     }
  553.     
  554.     /* Check if sectors per cluster make sense */
  555.     if (boot->b_spc != 2) {
  556.         ret = ERROR;
  557.         goto parmend;
  558.     }
  559.     
  560.     ret = OK;                /* If yes, return OK */
  561.  
  562. parmend:
  563.     return ret;
  564. }
  565.  
  566.  
  567. ichkparm(ldev)
  568. int ldev;
  569. {
  570.     char bs[512];        /* boot sector */
  571.     BOOT *boot;            /* boot structure */
  572.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  573.     int ret;
  574.  
  575.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  576.         if (tsterr(ret) != OK)
  577.             err(bootread);
  578.         ret = ERROR;
  579.         goto parmend;
  580.     }    
  581.  
  582.     boot = (BOOT *)bs;
  583.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  584.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  585.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  586.     if (bps != 512            /* bytes per sector == 512 ? */
  587.     || res != 1) {            /* num sectors reserved == 1 ? */
  588.     ret = ERROR;            /* Nope, different from assumptions */
  589.     goto parmend;
  590.     }
  591.     
  592.     /* Check if sectors per cluster make sense */
  593.     if ((siz >= 0x8000L && boot->b_spc != 4) ||
  594.         (siz < 0x8000L && boot->b_spc != 2)) {
  595.         ret = ERROR;
  596.         goto parmend;
  597.     }
  598.     
  599.     ret = OK;                /* If yes, return OK */
  600.  
  601. parmend:
  602.     return ret;
  603. }
  604.  
  605.  
  606. /*
  607.  * Get dev's root block.
  608.  *
  609.  */
  610. getroot(dev, buf, sect)
  611. int dev;
  612. char *buf;
  613. SECTOR sect;
  614. {
  615.     return rdsects(dev, 1, buf, sect);
  616. }
  617.  
  618.  
  619. /*
  620.  * Put dev's root block.
  621.  *
  622.  */
  623. putroot(dev, buf, sect)
  624. int dev;
  625. char *buf;
  626. SECTOR sect;
  627. {
  628.     return wrsects(dev, 1, buf, sect);
  629. }
  630.  
  631.  
  632. /*
  633.  *  Read sector(s) from dev.
  634.  *
  635.  *  Input:
  636.  *    dev - device number (logical or physical).
  637.  *    num - number of sectors to read.
  638.  *    buf - buffer to write data read.
  639.  *    sect - starting sector number to read from.
  640.  *
  641.  *  Return:
  642.  *    errnum - 0: if read is successful.
  643.  *         an error code: if read is unsuccessful.
  644.  */
  645. rdsects(dev, num, buf, sect)
  646. int dev;            /* device number (logical or physical) */
  647. UWORD num;            /* number of sectors to read */
  648. char *buf;
  649. SECTOR sect;            /* starting sector to read from */
  650. {
  651.     int errnum;
  652.  
  653.     if (log2phys(&dev, §) < 0)
  654.     return ERROR;
  655.  
  656.     ostack = Super(NULL);
  657.     errnum = hread(sect, num, buf, (UWORD)dev);
  658.     /*
  659.     if (errnum == 04)    {      the drive is stop 
  660.         delay();
  661.         stunt();
  662.         delay();
  663.         errnum = hread(sect, num, buf, (UWORD)dev);
  664.     }
  665.     */
  666.     delay();
  667.     Super(ostack);
  668.  
  669.     if (errnum > 0) {
  670.         errnum = errcode(dev);
  671.     }
  672.         
  673.     return errnum;        /* return the error code */
  674. }
  675.  
  676.  
  677. /*
  678.  *  Write sector(s) to dev.
  679.  *
  680.  *  Input:
  681.  *    dev - device number (logical or physical).
  682.  *    num - number of sectors to write.
  683.  *    buf - buffer with data to be written.
  684.  *    sect - starting sector number to write to.
  685.  *
  686.  *  Return:
  687.  *    errnum - 0: if write is successful.
  688.  *         an error code: if write is unsuccessful.
  689.  */
  690. wrsects(dev, num, buf, sect)
  691. int dev;            /* device number (logical or physical */
  692. UWORD num;            /* number of sectors to write */
  693. char *buf;            /* buffer with data to be written */
  694. SECTOR sect;            /* starting sector to write to */
  695. {
  696.     int errnum;
  697.  
  698.     if (log2phys(&dev, §) < 0)
  699.     return ERROR;
  700.  
  701.     ostack = Super(NULL);
  702.     errnum = hwrite(sect, num, buf, (UWORD)dev);
  703.     delay();
  704.     Super(ostack);
  705.  
  706.     if (errnum > 0) {
  707.         errnum = errcode(dev);
  708.     }
  709.  
  710.     return errnum;
  711. }
  712.  
  713.  
  714. /*
  715.  * Zero range of sectors on dev.
  716.  *
  717.  */
  718. zerosect(dev, start, count)
  719. int dev;
  720. SECTOR start;
  721. UWORD count;
  722. {
  723.     char *zbuf;
  724.     int  v;
  725.     UWORD i;
  726.  
  727.     if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
  728.         return err(nomemory);
  729.         
  730.     if (log2phys(&dev, &start) < 0) {
  731.         free(zbuf);
  732.     return ERROR;
  733.     }
  734.  
  735.     fillbuf(zbuf, (long)ZBUFSIZ, 0L);
  736.  
  737.     while (count)
  738.     {
  739.         if (count > ZCOUNT)
  740.             i = ZCOUNT;
  741.         else i = count;
  742.  
  743.     if ((v = wrsects(dev, i, zbuf, start)) != 0)
  744.         break;
  745.     start += i;
  746.     count -= i;
  747.     }
  748.     free(zbuf);
  749.     
  750.     return v;
  751. }
  752.